﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace WindowsFormsApplication1
{
    public delegate void ResultDelegate(string result);
    public class HttpSender
    {

        private static String DEFAULT_PARAMS_ENCODING = "UTF-8";            //文本格式

        private HttpWebRequest Request = null;
        private WebResponse Response = null;
        private Stream Stream = null;
        private StreamReader Read = null;
        private Byte[] Byte = null;               //本身就是数组
        private Encoding Encode = System.Text.Encoding.UTF8;
        //private System.Text.RegularExpressions.Match Match = null;

        //private IHttpResponseParser<T> parser;
        ResultDelegate resultDelegate;

        /// <summary>   
        /// 公开属性   
        /// </summary>   
        private WebProxy proxy = null;

        public void SetProxy(string ip, int port)
        {
            proxy = new WebProxy(ip, port);
        }

        public void SetErrorInovker(ResultDelegate resultDelegate)
        {
            this.resultDelegate = resultDelegate;
        }

        public void SetProxy(ProxyInfo proxInfo)
        {
            proxy = new WebProxy(proxInfo.IP, proxInfo.port);
        }

        public void ResetProxy()
        {
            proxy = null;
        }


        /// <summary>   
        /// 初始化Request   
        /// </summary>   
        /// <param name="Request">对象</param>   
        private void init_Request(ref HttpWebRequest Request)
        {
            //自动重定向   
            Request.AllowAutoRedirect = false;
            //代理设置   
            if (proxy != null && proxy.Address != null)
            {
                Request.Proxy = proxy;
                Request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36";
                Request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8";
                Request.Headers["Accept-Encoding"] = "gzip, deflate";
                Request.Headers["Accept-Language"] = " zh-CN,zh;q=0.8";
            }
            //其它杂项   
            Request.KeepAlive = true;
            Request.Timeout = 8000;
        }

        public string get_Internet(string url, string cookie = null)
        {
            try
            {
                Request = (HttpWebRequest)HttpWebRequest.Create(url);
                Request.Timeout = 300000;
                string result = null;
                if (Request != null)
                {
                    init_Request(ref Request);
                    if (cookie != null) { Request.Headers.Add("Cookie", cookie); }
                    using (Response = Request.GetResponse())
                    {
                        Stream = Response.GetResponseStream();
                        using (Read = new StreamReader(Stream, Encoding.UTF8))
                        {
                            result = Read.ReadToEnd();
                        }
                        Read = null;
                        Stream = null;
                    }
                    Response = null;
                    Request.Abort();
                    Request = null;
                }
                return result;
            }
            catch (Exception ex)
            {
                //Error.Write(ref ex);   
                if (resultDelegate != null)
                {
                    resultDelegate.Invoke(ex.Message);
                }
                return null;
            }
        }

        public string post_Internet(string url, Dictionary<String, String> reqParams)
        {
            string data = BuildHttpGetURL(url, reqParams);
            Console.WriteLine(data);


            string result = null;
            try
            {
                Request = (HttpWebRequest)HttpWebRequest.Create(url);
                if (Request != null)
                {

                    init_Request(ref Request);                             //请求初始化

                    Request.Method = "POST";                              //增加自己的属性
                    Request.ServicePoint.Expect100Continue = false;

                    Request.ContentType = getBodyContentType();

                    Byte = Encode.GetBytes(data);
                    Request.ContentLength = Byte.Length;

                    using (Stream = Request.GetRequestStream())
                    {
                        Stream.Write(Byte, 0, Byte.Length);
                    }
                    Stream = null;
                    Byte = null;
                    result = null;
                    using (Response = Request.GetResponse())
                    {
                        Stream = Response.GetResponseStream();
                        using (Read = new System.IO.StreamReader(Stream))
                        {
                            result = Read.ReadToEnd();
                        }
                        Read = null;
                        Stream = null;
                    }
                    Response = null;
                    Request.Abort();
                    Request = null;
                }
                return result;
            }
            catch (Exception ex)
            {
                //Error.Write(ref ex);
                if (resultDelegate != null)
                {
                    resultDelegate.Invoke(ex.Message);
                }

                return null;
            }
        }

        private static String getParamsEncoding()
        {
            return DEFAULT_PARAMS_ENCODING;
        }

        private static String getBodyContentType() //网络链接类型
        {
            return "application/x-www-form-urlencoded; charset=" + getParamsEncoding();
        }

        string BuildHttpGetURL(string baseURL, Dictionary<string, string> paramDict) //转化成为了请求的格式
        {
            StringBuilder sb = new System.Text.StringBuilder();
            sb.Append(baseURL);
            if (null != paramDict)
            {
                sb.Append("?");//添加符号
                foreach (var pair in paramDict)
                {
                    //TODO: urlencode
                    sb.Append("&");
                    sb.Append(pair.Key);
                    sb.Append("=");
                    sb.Append(pair.Value);
                }
            }

            return sb.ToString();
        }
    }
}



